home *** CD-ROM | disk | FTP | other *** search
/ Beginning Mac Programming / Beginning Mac Programming.bin / pc / Open Me for REALbasic 3 / REALbasic 3.2 / Goodies / 3rd Party Demos / 3rd Party Plugins / Misc / PEVocoder 1.0 (PPC) / PEVocodePlugin Source Code / riff.cp < prev    next >
Encoding:
Text File  |  2000-11-22  |  4.2 KB  |  141 lines

  1. /******************************************************************************
  2.  * $Id: riff.c,v 1.2 1998/09/13 00:21:18 emanuel Exp $
  3.  * Copyright (C) 1996-1998 Emanuel Borsboom <emanuel@zerius.com>
  4.  * Permission is granted to make any use of this code subject to the condition
  5.  * that all copies contain this notice and an indication of what has been
  6.  * changed.
  7.  *****************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include "config.h"
  11. #include "error.h"
  12. #include "wave.h"
  13. #include "riff.h"
  14.  
  15. WAVE_FILE *riff_open(FILE *fp, WAVE_INFO *info)
  16. {
  17.   char file_id[5], form_type[5];
  18.   INT file_data_size, file_position;
  19.   SHORT format_tag = 0, channels = 0, block_align, bits_per_sample = 0;
  20.   INT samples_per_sec = 0, avg_bytes_per_sec;
  21.   INT data_size = 0, length;
  22.   long data_offset = 0;
  23.   BOOL got_format_chunk = FALSE, got_data_chunk = FALSE;
  24.   WAVE_FILE *file;
  25.   
  26.   fread(file_id, 4, 1, fp);
  27.   file_id[4] = '\0';
  28.   if (strcmp(file_id, "RIFF") != 0)
  29.     return NULL;
  30.   
  31.   file_data_size = wave_read_int_little(fp) + 8;
  32.   
  33.   fread(form_type, 4, 1, fp);
  34.   form_type[4] = '\0';
  35.   if (strcmp(form_type, "WAVE") != 0)
  36.     return NULL;
  37.  
  38.   file_position = 12;
  39.   while (file_position < file_data_size)
  40.     {
  41.       char chunk_id[5];
  42.       INT chunk_data_size;
  43.  
  44.       if (fread(chunk_id, 4, 1, fp) < 1)
  45.         {
  46.           if (feof(fp))
  47.             error("riff_open: bad format: EOF encountered where chunk expected");
  48.           else if (ferror(fp))
  49.             error("riff_open: bad format: error encountered where chunk expected: %s",
  50.                   strerror(errno));
  51.         }
  52.       chunk_id[4] = '\0';
  53.  
  54.       chunk_data_size = wave_read_int_little(fp);
  55.  
  56.       if (strcmp(chunk_id, "fmt ") == 0)
  57.         /* Common chunk */
  58.         {
  59.           format_tag = wave_read_short_little(fp);
  60.           channels = wave_read_short_little(fp);
  61.           samples_per_sec = wave_read_int_little(fp);
  62.           avg_bytes_per_sec = wave_read_int_little(fp);
  63.           block_align = wave_read_short_little(fp);
  64.           if (format_tag == 1)
  65.             {
  66.               bits_per_sample = wave_read_short_little(fp);
  67.             }
  68.           got_format_chunk = TRUE;
  69.         }
  70.       else if (strcmp(chunk_id, "data") == 0)
  71.         /* Sound Data chunk */
  72.         {
  73.           data_size = chunk_data_size;
  74.           data_offset = ftell(fp);
  75.           got_data_chunk = TRUE;
  76.         }
  77.  
  78.       file_position += chunk_data_size + 8;
  79.       fseek(fp, file_position, SEEK_SET);
  80.     }
  81.  
  82.   if (!got_format_chunk)
  83.     error("riff_open: bad format: format chunk not found");
  84.   if (!got_data_chunk)
  85.     error("riff_open: bad format: data chunk not found");
  86.   if (format_tag != 1)
  87.     error("riff_open: bad format: only PCM data is supported");
  88.  
  89.   length = data_size / ((bits_per_sample + 7) / 8);
  90.  
  91.   fseek(fp, data_offset, SEEK_SET);
  92.  
  93.   file = (tag_WAVE_FILE*)error_malloc(sizeof(WAVE_FILE));//EJT
  94.   file->is_big_endian = FALSE;
  95.   file->sample_offset = (bits_per_sample <= 8) ? 128 : 0;
  96.  
  97.   info->rate = samples_per_sec;
  98.   info->bits = bits_per_sample;
  99.   info->channels = channels;
  100.   info->length = length;
  101.  
  102.   return file;
  103. }
  104.  
  105. WAVE_FILE *riff_create(FILE *fp, WAVE_INFO *info)
  106. {
  107.   WAVE_FILE *file;
  108.   
  109.   fwrite("RIFF", 4, 1, fp);
  110.   wave_write_int_little(0xDEADBEEF, fp);
  111.   fwrite("WAVE", 4, 1, fp);
  112.  
  113.   fwrite("fmt ", 4, 1, fp);
  114.   wave_write_int_little(16, fp);
  115.   wave_write_short_little(1, fp);
  116.   wave_write_short_little(info->channels, fp);
  117.   wave_write_int_little(info->rate, fp);
  118.   wave_write_int_little(info->channels * info->rate * ((info->bits + 7) / 8), fp);
  119.   wave_write_short_little(info->channels * ((info->bits + 7) / 8), fp);
  120.   wave_write_short_little(info->bits, fp);
  121.  
  122.   fwrite("data", 4, 1, fp);
  123.   wave_write_int_little(0xDEADBEEF, fp);
  124.  
  125.   file = (tag_WAVE_FILE*)error_malloc(sizeof(WAVE_FILE));//EJT
  126.   file->is_big_endian = FALSE;
  127.   file->sample_offset = (info->bits <= 8) ? 128 : 0;
  128.   return file;
  129. }
  130.  
  131. void riff_close(WAVE_FILE *file)
  132. {
  133.   if (file->open_mode == WAVE_WRITE_MODE)
  134.     {
  135.       fseek(file->fp, 4, SEEK_SET);
  136.       wave_write_int_little(file->length * ((file->bits + 7) / 8) + 4 + 8 + 16 + 8, file->fp);
  137.       fseek(file->fp, 12 + 8 + 16 + 4, SEEK_SET);
  138.       wave_write_int_little(file->length * ((file->bits + 7) / 8), file->fp);
  139.     }
  140. }
  141.